package br.ufal.tci.nexos.arcolive;

import java.util.Enumeration;
import java.util.Hashtable;

import br.ufal.tci.nexos.arcolive.descriptors.ParticipantDescriptor;
import br.ufal.tci.nexos.arcolive.descriptors.ServiceDescriptor;
import br.ufal.tci.nexos.arcolive.descriptors.ServiceInstanceDescriptor;
import br.ufal.tci.nexos.arcolive.exception.ArCoLIVECannotAddServiceInstanceException;
import br.ufal.tci.nexos.arcolive.participant.ArCoLIVEParticipant;

public final class ArCoLIVEServicePoll {
	private Hashtable services;
	
	public ArCoLIVEServicePoll() {
		this.services = new Hashtable();
	}

	public void addService(ArCoLIVEService service) {
		this.services.put(service, new ArCoLIVEServiceInstanceGroup(service.getMaxInstances()));
	}
	
	public ArCoLIVEService getService(int serviceId) {
		ArCoLIVEService service = new ArCoLIVEService(serviceId);
		Enumeration services = this.services.keys();
		while (services.hasMoreElements()) {
			ArCoLIVEService aService = (ArCoLIVEService) services.nextElement();
			if (service.equals(aService)) {
				return aService;
			}
		}
		return null;
	}
	
	public ArCoLIVEServiceInstance[] getServiceInstances(ArCoLIVEService service) {
		ArCoLIVEServiceInstanceGroup serviceInstanceGroup = (ArCoLIVEServiceInstanceGroup)this.services.get(service);
		
		if (serviceInstanceGroup == null) {
			return new ArCoLIVEServiceInstance[0];
		}
		return serviceInstanceGroup.getServiceInstances();
	}
	
	public ArCoLIVEServiceInstance getServiceInstance(int serviceId, int serviceInstanceId) {
		return getServiceInstance(new ArCoLIVEService(serviceId), serviceInstanceId);
	}
	
	public ArCoLIVEServiceInstance getServiceInstance(ArCoLIVEService service, int serviceInstanceId) {
		ArCoLIVEServiceInstanceGroup serviceInstanceGroup = (ArCoLIVEServiceInstanceGroup) this.services.get(service);
		return serviceInstanceGroup.getServiceInstanceById(serviceInstanceId);
	}
	
	public void addServiceInstance(ArCoLIVEService service, ArCoLIVEServiceInstance serviceInstance) throws ArCoLIVECannotAddServiceInstanceException {
		ArCoLIVEServiceInstanceGroup serviceInstanceGroup = (ArCoLIVEServiceInstanceGroup) this.services.get(service);
		serviceInstanceGroup.addServiceInstance(serviceInstance);		
	}
	
	public ServiceDescriptor[] getServiceDescriptors() {
		Enumeration services = this.services.keys();
		int i=0;
		while (services.hasMoreElements()) {
			services.nextElement();
			i++;			
		}

		ServiceDescriptor serviceDescriptors[] = new ServiceDescriptor[i];
		
		i=0;
		
		services = this.services.keys();
		while (services.hasMoreElements()) {
			ArCoLIVEService service = (ArCoLIVEService)services.nextElement();
			serviceDescriptors[i] = new ServiceDescriptor(service);
			serviceDescriptors[i].setInstancesDescriptors(this.getServiceInstancesDescriptors(service));
			i++;
			
		}
		
		return serviceDescriptors;
	}
	
	public ServiceInstanceDescriptor[] getServiceInstancesDescriptors(int serviceId) {
		return this.getServiceInstancesDescriptors(new ArCoLIVEService(serviceId));
	}
	
	public ServiceInstanceDescriptor[] getServiceInstancesDescriptors(ArCoLIVEService service) {
		ArCoLIVEServiceInstance[] serviceInstances = this.getServiceInstances(service);
		
		ServiceInstanceDescriptor serviceInstanceDescriptors[] = new ServiceInstanceDescriptor[serviceInstances.length];
		
		for (int j = 0; j < serviceInstances.length; j++) {
			serviceInstanceDescriptors[j] = serviceInstances[j].getServiceInstanceDescriptor();
		}

		return serviceInstanceDescriptors;
	}
	
	public ParticipantDescriptor[] getParticipantDescriptors(int serviceId, int serviceInstanceId) {
		return this.getParticipantDescriptors(new ArCoLIVEService(serviceId), serviceInstanceId);
	}
	
	public ParticipantDescriptor[] getParticipantDescriptors(ArCoLIVEService service, int serviceInstanceId) {
		ArCoLIVEServiceInstance serviceInstance = this.getServiceInstance(service, serviceInstanceId);
		ArCoLIVEParticipant participants[] = serviceInstance.getParticipantGroup().getParticipants();
		ParticipantDescriptor participantDescriptors[] = new ParticipantDescriptor[participants.length];
		
		for (int i = 0; i < participants.length; i++) {
			participantDescriptors[i] = participants[i].getParticipantDescriptor();
		}
		
		return participantDescriptors;
	}

	public static void main(String[] args) {
		ArCoLIVEServicePoll sp = new ArCoLIVEServicePoll();
		ArCoLIVEService service = new ArCoLIVEService(700);
		service.setMaxInstances(10);
		sp.addService(service);
		System.out.println(sp.getServiceInstancesDescriptors(700));
	}
	
}
